package com.hzlj.position.locate.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.fz.common.base.dto.PageParamDTO;
import com.fz.common.base.dto.QueryPageResultDTO;
import com.fz.common.base.exception.PubException;
import com.fz.common.dict.annotation.DictConvert;
import com.hzlj.position.config.common.dto.common.PositionCommonDTO;
import com.hzlj.position.config.common.dto.common.PositionHandleExtDTO;
import com.hzlj.position.config.common.dto.common.PositionHandleQueryResultDTO;
import com.hzlj.position.config.config.PositionConfig;
import com.hzlj.position.locate.common.common.PositionWithExtDTO;
import com.hzlj.position.locate.common.common.PositionWithHandleDTO;
import com.hzlj.position.locate.common.common.ReadUpdateDTO;
import com.hzlj.position.locate.common.dto.position.*;
import com.hzlj.position.locate.common.model.Position;
import com.hzlj.position.locate.dao.PositionDao;
import com.hzlj.position.locate.differentiation.positionWarningHandle.PositionWarningHandle;
import com.hzlj.position.locate.service.PositionNewestEffectiveService;
import com.hzlj.position.locate.service.PositionNewestService;
import com.hzlj.position.locate.service.PositionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.hzlj.position.config.common.constant.Topic.*;


/**
 * 定位记录-分表(Position)表服务接口
 *
 * @author lifh
 * @date 2023-03-16 12:48:18
 */
@Slf4j
@Service
public class PositionServiceImpl implements PositionService {
    @Resource
    private PositionDao positionDao;
    @Resource
    private PositionConfig positionConfig;
    @Resource
    private PositionNewestService positionNewestService;
    @Resource
    private PositionNewestEffectiveService positionNewestEffectiveService;
    @Resource
    private PositionWarningHandle positionWarningHandle;
    @Resource
    private KafkaTemplate kafkaTemplate;

    @Override
    @DictConvert
    public PositionQueryResultDTO getPosition(String id, Date positionTime) {
        PositionQueryResultDTO position = this.positionDao.getPosition(id, positionTime);
        if (position == null) {
            throw new PubException("查询定位失败，请确认参数是否正确");
        }
        return position;

    }

    @Override
    public PositionExtDTO getPositionExt(String id, Date positionTime) {
        return positionDao.getPositionExt(id, positionTime);
    }

    @Override
    public void updatePositionExt(String id, Date positionTime, PositionExtDTO positionExt) {
        positionDao.updatePositionExt(id, positionTime, positionExt);
    }


    @Override
    public void saveBatch(List<Position> positions) {
        if (ObjectUtil.isEmpty(positions)) {
            return;
        }
        //批量保存
        positionDao.saveBatch(positions);
    }

    @Override
    public List<PositionCommonDTO> listPosition4Abn(String jgCode, Date startTime, Date endTime) {
        PositionQueryParamDTO params = new PositionQueryParamDTO();
        params.setJgCode(jgCode);
        params.setStartPositionTime(startTime);
        params.setStartPositionTime(endTime);
        params.setHasPosition(true);
        return this.positionDao.listPositionCommon(params);
    }

    @Override
    public List<PositionCommonDTO> listPosition4AbnByJzId(String jzId, Date startTime, Date endTime) {
        PositionQueryParamDTO params = new PositionQueryParamDTO();
        params.setJzId(jzId);
        params.setStartPositionTime(startTime);
        params.setEndPositionTime(endTime);
        params.setHasPosition(true);
        return this.positionDao.listPositionCommon(params);
    }

    @Override
    public List<PositionWithHandleDTO> listPosition4Handle(PositionQueryParamDTO params) {
        params.setWarning(true);
        return this.positionDao.listPosition4Handle(params);
    }

    @Override
    @DictConvert
    public List<PositionQueryResultDTO> listPosition(PositionQueryParamDTO dto) {
        List<PositionQueryResultDTO> positions = this.positionDao.listPosition(dto);
        this.fillPositions(positions);
        return positions;
    }

    /**
     * 查询列表：分页
     */
    @Override
    @DictConvert
    public QueryPageResultDTO<PositionQueryResultDTO> pagePosition(PositionQueryParamDTO dto, PageParamDTO page) {
        QueryPageResultDTO<PositionQueryResultDTO> result = this.positionDao.pagePosition(dto, page);
        this.fillPositions(result.getList());
        return result;
    }


    @Override
    @Transactional
    @SuppressWarnings("unchecked")
    public void handle(PositionHandleDTO dto) {
        this.positionDao.handle(dto);
        //更新newest
        this.positionNewestService.handle(dto);
        //更新最新记录
        positionNewestEffectiveService.handle(dto);
        //异常处理
        this.positionWarningHandle.handle(dto);
        //发送通知
        this.kafkaTemplate.send(POSITION_HANDLE, dto);
    }

    @Override
    @Transactional
    public void handleSysCheck(PositionHandleDTO dto) {
        this.positionDao.handleSysCheck(dto);
        //更新newest
        this.positionNewestService.handleSysCheck(dto);
    }

    @Override
    public void read(ReadUpdateDTO dto) {
        this.positionDao.read(dto);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void sync(PositionQueryParamDTO dto) {
//        List<PositionWithExtDTO> positions = this.positionDao.listPositionWithExt(dto);
//        log.info("手动一键同步：size={}", positions.size());
//        kafkaTemplate.send(POSITION_SYNC, positions);
    }

    @Override
    public void updateSync(PositionSyncDTO sync) {
        for (PositionWithExtDTO position : sync.getPositions()) {
            PositionExtDTO positionExt = position.getPositionExt();
            positionExt.setSyncTime(sync.getSyncTime());
            positionExt.setSyncMsg(sync.getSyncMsg());
            this.positionDao.updateSyncStatus(position.getId(), position.getPositionTime(), sync.getSyncStatus(), positionExt);
        }
    }

    @Override
    public PositionHandleQueryResultDTO getHandleResult(String id, Date positionTime) {
        return this.positionDao.getHandleResult(id, positionTime);
    }

    @Override
    public PositionHandleExtDTO getHandleResultExt(String id, Date positionTime) {
        return this.positionDao.getHandleResultExt(id, positionTime);
    }

    @Override
    public List<String> listJzIds4Effective(Date startTime, Date endTime) {
        return this.positionDao.listJzIds4Effective(startTime, endTime);
    }


    private void fillPositions(List<PositionQueryResultDTO> positions) {
        if (ObjectUtil.isEmpty(positions)) {
            return;
        }
        //已读消息维护
        List<String> warningTypes = Arrays.stream(positionConfig.getReadWarningTypes().split(","))
                .collect(Collectors.toList());
        for (PositionQueryResultDTO position : positions) {
            //已读未读
            if (warningTypes.contains(position.getWarningType())) {
                position.setReadText(
                        Boolean.TRUE.equals(position.getRead()) ? "已读" : "未读"
                );
            } else {
                position.setReadText("/");
            }
        }
    }
}
